package com.rgbgame.editor;

import processing.core.PApplet;//import com.rgbgame.editor.rgbEditor.com.rgbgame.editor.UIDockWidget;

/**
 * 
 */

class UIDock{
			/**
			 * 
			 */
			private final rgbEditor editor;
			//For now, just a dock on the left side of the screen
			public float dockWidth;
			public float dockHeight;
			public float x;  //Upper left coordinates
			public float y;
			public float maxDockHeight;
			public UIDockWidget[] widgets;
			public boolean UITrap;
			public float dockMouseOverWidth;
			private float originalY;
			private float originalHeight;
			private float drawnY;
			private float drawnHeight;
			private float easeSpeed;

    private int height = rgbEditor.pApplet.height;

            {
				easeSpeed = .3f;
			}

			public void selectWidget(UIDockWidget me){
				for (int i=0; i<widgets.length; i++){
                    widgets[i].selectedFlag = (widgets[i] == me);
				}
				this.editor.clearDraggedLine();
			}

			public UIDock(rgbEditor editor, float _x,float _y,float _width,float _height,float _maxHeight){
				this.editor = editor;
				x=_x; y=_y; dockWidth=_width; dockHeight=_height; maxDockHeight=_maxHeight;
				dockMouseOverWidth = dockWidth;
				widgets = new UIDockWidget[0];
				UITrap = false;
				originalY = y;
				originalHeight = dockHeight;
				drawnY = y;
				drawnHeight = dockHeight;
			}

			public UIDock(rgbEditor editor){
                this.editor = editor;
				x = 0;
				dockWidth = 40.0f;
				dockMouseOverWidth = dockWidth;
				dockHeight = height*.8f;
				y = height/2.0f - dockHeight/2.0f;
				maxDockHeight = height*.9f;
				widgets = new UIDockWidget[0];
				UITrap = false;
				originalY = y;
				originalHeight = dockHeight;
				drawnY = y;
				drawnHeight = dockHeight;
			}

			public void addWidget(UIDockWidget newWidget){
				UIDockWidget[] buffer = new UIDockWidget[widgets.length+1];
				originalHeight = 0;
				for (int i=0; i<widgets.length; i++){
					buffer[i] = widgets[i];
					originalHeight += widgets[i].preferredWidgetHeight;
				}
				originalHeight = PApplet.min(originalHeight,maxDockHeight);
				originalY = height/2.0f - originalHeight/2.0f;
				buffer[widgets.length] = newWidget;
				newWidget.parent = this;
				widgets = buffer;
			}

			public void go(){
				//Called once all widgets have been added
				setDimensions();
			}

			private void setDimensions(){
				//Sets dock dimensions based on current widget sizes
				//Don't use this function for the dynamic stuff, just for the initial dimensions setting!
				float newHeight = 0;
				for (int i=0; i<widgets.length; i++){
					newHeight += widgets[i].preferredWidgetHeight;
				}
//				if (newHeight > maxDockHeight){
				float multiplier = 1.0f;
				if (newHeight > maxDockHeight){multiplier = maxDockHeight / newHeight;}
				float maxWidth = 0;
				for (int i=0; i<widgets.length; i++){
					widgets[i].widgetHeight = widgets[i].preferredWidgetHeight * multiplier;
					widgets[i].normalWidgetHeight = widgets[i].preferredWidgetHeight * multiplier;
					widgets[i].widgetWidth = widgets[i].preferredWidgetWidth * multiplier;
					widgets[i].normalWidgetWidth = widgets[i].preferredWidgetWidth * multiplier;
					if (widgets[i].widgetWidth > maxWidth) {maxWidth = widgets[i].widgetWidth;}
				}
				if (multiplier < 0.999f){newHeight = maxDockHeight;}
				dockMouseOverWidth = maxWidth;
				dockWidth = PApplet.min(maxWidth,dockWidth);

//				}
			dockHeight = newHeight;
			y = height/2.0f - dockHeight/2.0f;
			originalY = y;
			originalHeight = dockHeight;
//			targetHeight = dockHeight;
			float currentLoc = y;
			for (int i=0; i<widgets.length; i++){
				widgets[i].x = 0;
				widgets[i].y = currentLoc;
				currentLoc += widgets[i].widgetHeight;
			}
			}


			private void dynamicSetDimensions(){

				float newHeight = 0;
				for (int i=0; i<widgets.length; i++){
					newHeight += widgets[i].widgetHeight;
				}
				float maxWidth = 0;
				for (int i=0; i<widgets.length; i++){
					if (widgets[i].widgetWidth > maxWidth) {maxWidth = widgets[i].widgetWidth;}
				}
				dockMouseOverWidth = maxWidth;
//				}
				dockHeight = newHeight;
				//targetHeight = newHeight;
				//y = height/2.0 - dockHeight/2.0;
				float currentLoc = y;
				for (int i=0; i<widgets.length; i++){
					widgets[i].x = 0;
					widgets[i].y = currentLoc;
					currentLoc += widgets[i].widgetHeight;
				}
			}

			private void nudgeDock(float downBy){
				y += downBy;
				for (int i=0; i<widgets.length; i++){
					widgets[i].y += downBy;
				}
			}

			public void drawWidgets(){
				for (int i=0; i<widgets.length; i++){
					widgets[i].draw();
				}
			}

			public void drawDock(){
                PApplet p = rgbEditor.pApplet;
                drawnY = drawnY*(1.0f-easeSpeed)+easeSpeed*y;
				drawnHeight = drawnHeight*(1.0f-easeSpeed)+easeSpeed*dockHeight;
				p.stroke(160,160,180);
				p.fill(255,255,255,100);
				p.rect(x,drawnY,dockWidth,drawnHeight);
				p.noFill();
				if(this.editor.focusLock== rgbEditor.NONE||this.editor.focusLock==rgbEditor.DOCK){checkMouseOver();}
				drawWidgets();
			}

			public void transformWidgets(){
                PApplet p = rgbEditor.pApplet;
                float mouseOffset = p.mouseY-originalY; //want pixel-perfect alignment between untransformed mouse target and transformed target
				float transformedMouseOffset = p.mouseY-originalY;
				float currentY = originalY;
				y = currentY;
				for (int i=0; i<widgets.length; i++){
					currentY += widgets[i].normalWidgetHeight / 2.0f;
					float scalingFactor = bulge(currentY-p.mouseY);
					if (currentY-widgets[i].normalWidgetHeight/2.0f < p.mouseY && currentY+widgets[i].normalWidgetHeight/2.0f > p.mouseY){
						//mouse lies within this region
						transformedMouseOffset += widgets[i].normalWidgetHeight*(scalingFactor-1.0f)*( p.mouseY-currentY+widgets[i].normalWidgetHeight/2.0f )/(widgets[i].normalWidgetHeight);
					} else if (currentY-widgets[i].normalWidgetHeight/2.0f < p.mouseY){
						transformedMouseOffset += widgets[i].normalWidgetHeight*scalingFactor-widgets[i].normalWidgetHeight;
					}
//					widgets[i].targetWidgetHeight = widgets[i].normalWidgetHeight*scalingFactor;
//					widgets[i].targetWidgetWidth = widgets[i].normalWidgetWidth*scalingFactor;
					widgets[i].widgetHeight = widgets[i].normalWidgetHeight*scalingFactor;
					widgets[i].widgetWidth = widgets[i].normalWidgetWidth*scalingFactor;
					currentY += widgets[i].normalWidgetHeight / 2.0f;
				}
				nudgeDock(-(transformedMouseOffset-mouseOffset));
//				println(transformedMouseOffset+"; "+mouseOffset);

			}

			private float bulge(float b){
				float bulgeFactor = 0.5f;
				float bScale = 70.0f;
				return 1.0f+bulgeFactor* PApplet.exp(-b*b/(bScale*bScale));
			}

			private void setHeightFromWidgets(){
				float h = 0;
				for(int i=0; i<widgets.length; i++){
					h += widgets[i].widgetWidth;
				}
				dockHeight = h;
			}

			public boolean checkMouseOver(){
                PApplet p = rgbEditor.pApplet;
                setHeightFromWidgets();
				//Checks mouseOver status and passes message to widgets
				if (p.mouseX < x+dockMouseOverWidth && p.mouseX > x && p.mouseY < y+dockHeight && p.mouseY > y){
					//Insert other tests, such as whether something else already has mouse focus
					transformWidgets();
					dynamicSetDimensions();
					for (int i=0; i<widgets.length; i++){
						if (p.mousePressed && p.mouseButton== PApplet.LEFT){
							if (p.mouseX < widgets[i].x+widgets[i].widgetWidth && p.mouseX > widgets[i].x && p.mouseY < widgets[i].y+widgets[i].widgetHeight && p.mouseY > widgets[i].x){
								widgets[i].onSelect();
								break;
							}
						}
						else if((p.mouseX < widgets[i].x+widgets[i].widgetWidth && p.mouseX > widgets[i].x && p.mouseY < widgets[i].y+widgets[i].widgetHeight && p.mouseY > widgets[i].x)){
							widgets[i].onHover();
							break;
						}
					}
					UITrap = true;
//					setHeightFromWidgets();
					return true;
				} else{
					setDimensions();
					//dynamicSetDimensions();
					UITrap = false;
//					setHeightFromWidgets();
					return false;
				}
			}


		}